#region File Description
//-----------------------------------------------------------------------------
// GameplayScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Threading;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SpriteLib;
using SharedCongkak;
#endregion

namespace Congkak
{
    /// <summary>
    /// This screen implements the actual game logic. It is just a
    /// placeholder to get the idea across: you'll probably want to
    /// put some more interesting gameplay in here!
    /// </summary>
    public class GameplayScreen : GameScreen
    {
        #region Fields

        ContentManager content;
        SpriteFont gameFont;
        SpriteFont numFont;
        Texture2D backgroundTexture;
        Rectangle viewportRect;
        List<BasicLevel> ListOfLevels = new List<BasicLevel>();
        BasicLevel level;
        SeedQueue seedQueue;
        GameState gameState;

        SpriteText displayScore;
        SpriteText displayScore2;

        int score;
        Vector2 scorePosition = new Vector2(50, 50);

        #endregion
        #region Initialization


        /// <summary>
        /// Constructor.
        /// </summary>
        public GameplayScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);

            Sound.Play(SoundEntry.MusicGame);

        }


        /// <summary>
        /// Load graphics content for the game.
        /// </summary>
        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            Viewport viewport = ScreenManager.Game.GraphicsDevice.Viewport;
            viewportRect = new Rectangle(0, 0, viewport.Width, viewport.Height);

            gameFont = content.Load<SpriteFont>("Font/gamefont");
            numFont = content.Load<SpriteFont>("Font/DamageFont");
            backgroundTexture = content.Load<Texture2D>("Texture/flowerbackground");
            Seed.LoadContent(content);

            level = new BasicLevel(ScreenManager.Game);
            ScreenManager.Game.Components.Add(level);
            ScreenManager.Game.Services.AddService(typeof(ILevel), level);

            gameState = new EditState(this);
            ScreenManager.Game.Services.AddService(typeof(GameState), gameState);
            level.OnSeedAddedToHole += SeedAddedToHole;
            //level.LoadLevel(content);
            
            seedQueue = new SeedQueue();
            displayScore = new SpriteText()
            {
                Position = scorePosition + new Vector2(400, 100),
                SpriteFont = gameFont,
                Orientation = 0,
                Color = Color.AliceBlue,
                Text = "TestFadeText"
            };

            displayScore2 = new SpriteText()
            {
                Position = scorePosition + new Vector2(400, 100),
                SpriteFont = gameFont,
                Orientation = 0,
                Color = Color.Black,
                Text = "TestFadeText"
            };


            ISpriteEffect fadeEffect = new SpriteFadeEffect(255, 0, TimeSpan.Zero, new TimeSpan(0, 0, 5));
            displayScore.AttachSpriteEffect(fadeEffect);
            ISpriteEffect moveEffect = new SpriteMoveEffect(
                displayScore.Position,
                displayScore.Position + new Vector2(0, -50),
                TimeSpan.Zero,
                new TimeSpan(0, 0, 5));
            displayScore.AttachSpriteEffect(moveEffect);
            ISpriteEffect scaleEffect = new SpriteScaleEffect(
                displayScore.Scale,
                1.5f,
                TimeSpan.Zero,
                new TimeSpan(0, 0, 5));
            displayScore.AttachSpriteEffect(scaleEffect);
            //ISpriteEffect colorEffect = new SpriteColorEffect(
            //    Color.White,
            //    Color.Pink,
            //    TimeSpan.Zero,
            //    new TimeSpan(0, 0, 5));
            //displayScore.AttachSpriteEffect(colorEffect);
            
            // A real game would probably have more content than this sample, so
            // it would take longer to load. We simulate that by delaying for a
            // while, giving you a chance to admire the beautiful loading screen.
            //Thread.Sleep(1000);

            // once the load has finished, we use ResetElapsedTime to tell the game's
            // timing mechanism that we have just finished a very long frame, and that
            // it should not try to catch up.
            ScreenManager.Game.ResetElapsedTime();
        }


        /// <summary>
        /// Unload graphics content used by the game.
        /// </summary>
        public override void UnloadContent()
        {
            content.Unload();
        }


        #endregion

        #region Update and Draw


        /// <summary>
        /// Updates the state of the game. This method checks the GameScreen.IsActive
        /// property, so the game will stop updating when the pause menu is active,
        /// or if you tab away to a different application.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            gameState.Update(gameTime);
            displayScore.Update(gameTime);
            //level.Update(gameTime);
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);            
        }


        /// <summary>
        /// Lets the game respond to player input. Unlike the Update method,
        /// this will only be called when the gameplay screen is active.
        /// </summary>
        public override void HandleInput(InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            // Look up inputs for the active player profile.
            int playerIndex = (int)ControllingPlayer.Value;
            

            KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];
            GamePadState gamePadState = input.CurrentGamePadStates[playerIndex];

            // The game pauses either if the user presses the pause button, or if
            // they unplug the active gamepad. This requires us to keep track of
            // whether a gamepad was ever plugged in, because we don't want to pause
            // on PC if they are playing with a keyboard and have no gamepad at all!
            bool gamePadDisconnected = !gamePadState.IsConnected &&
                                       input.GamePadWasConnected[playerIndex];

            if (input.IsPauseGame(ControllingPlayer) || gamePadDisconnected)
            {
                ScreenManager.AddScreen(new PauseMenuScreen(), ControllingPlayer);
            }
            else
            {
                //level.HandleInput(input, ControllingPlayer);
                gameState.HandleInput(input, ControllingPlayer);
            }
           
        }

        public void CollectFromHole(Hole selectedHole)
        {
            ChangeGameState(new CollectingState(this, selectedHole, seedQueue));

        }

        private void SeedAddedToHole(object sender, HoleEventArgs holeEventArgs)
        {
            if(sender is Store)
                score += holeEventArgs.Seed.Score;
        }

        public void NextLevel()
        {
            score = 0;
        }

        public void RetryLevel()
        {
            score = 0;
            ScreenManager.Game.Services.RemoveService(typeof(ILevel));
            ScreenManager.Game.Components.Remove(level);
            level = new BasicLevel(ScreenManager.Game);
            level.OnSeedAddedToHole += SeedAddedToHole;
            ScreenManager.Game.Components.Add(level);
            ScreenManager.Game.Services.AddService(typeof(ILevel), level);

            //level.LoadLevel(content);
            gameState = new PickState(this);
        }


        public void ChangeGameState(GameState state)
        {
            ScreenManager.Game.Services.RemoveService(typeof(GameState));
            this.gameState = state;
            ScreenManager.Game.Services.AddService(typeof(GameState), state);
        }




        /// <summary>
        /// Draws the gameplay screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {

            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
                                               Color.Black, 0, 0);

            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            spriteBatch.Begin();

            spriteBatch.Draw(backgroundTexture, viewportRect, Color.White);
            level.Draw(spriteBatch);
            spriteBatch.DrawString(gameFont, "Score: " + score.ToString(), scorePosition, Color.AliceBlue);
            seedQueue.Draw(spriteBatch);
            displayScore2.Draw(spriteBatch);
            displayScore.Draw(spriteBatch);
            spriteBatch.End();

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0)
                ScreenManager.FadeBackBufferToBlack(255 - TransitionAlpha);
        }


        #endregion
    }
}
